export const types = ['number','string','boolean','array','null','undefined','regexp','function']
const publicPath = 'my-demo';


export const type = (arg) => {
  const s = Object.prototype.toString.call(arg)
  const r = /^\[\w+\s(\w+)\]$/.exec(s);
  return r[1].toLowerCase();
}
const ExtKeys = ['this']
export const expres = (s,ctx = {}) => {
  try {
    const keys = Object.keys(ctx).filter((k) => !ExtKeys.includes(k));
    const vals = keys.map((k) => ctx[k]);
    const str = "return " + s;
    return new Function(...keys, str)(...vals);
  } catch (e) {
    console.error('====表达式解析异常！=====',e);
  }
  return undefined;
}

// const JSON
export const json2str = (v) => {
  try {
    if(typeof v == 'function'){
      return '{FUNCTION}' + String(v);
    }
    return v;
  } catch (error) {
    console.error(error)
  }
}

export const json2source = (v) => {
  if(/^\{FUNCTION\}/.test(v)){
    return new Function('return ' + v.replace('{FUNCTION}',''))
  }
  return v;
}

// 序列化
export const serialize = (v) => {
  switch(type(v)){
    case 'array':return JSON.stringify(v,(k,v) => json2str(v));
    case 'object':return JSON.stringify(v,(k,v) => json2str(v));
    case 'undefined':return 'undefined';
    case 'null':return 'null';
    case 'function':return String(v);
    case 'boolean':return String(v);
    case 'regexp':return String(v);
  }
  return v
}
// 反序列化
export const unserialize = (s,t) => {
  switch(t){
    case 'array':return JSON.parse(s,(k,v) => json2source(v));
    case 'object':return JSON.parse(s,(k,v) => json2source(v));
    case 'undefined':return undefined;
    case 'null':return null;
    case 'function':return new Function('return ' + s);
    case 'boolean':return s == 'true' ? true : false;
    case 'regexp':return new RegExp(s.slice(1,-1));
  }
  return s;
}

// localstorage 保存数据
export const saveLocal = (key, val) => {
  const t = type(val);
  const v = serialize(val);

  const c = {
    time:new Date().getTime(),
    type:t,
    value:v
  }
  localStorage.setItem(key, JSON.stringify(c));
};
// 取出数据
export const getLocal = (key,source = false) => {
  const s = localStorage.getItem(key);
  if(s && /^{/.test(s)){
    const c = JSON.parse(s);
    c.value = unserialize(c.value,c.type)
    //
    if(source){
      return c;
    }
    return c.value;
  }
  return undefined;
}

//
export const modelLocalKey = 'PAGE_MODEL_DATA'
export const saveModelData = (md) => {
  const key = modelLocalKey;
  saveLocal(key,md)
}

export const getModelData = async () => {
  const key = modelLocalKey;
  const res = getLocal(key);
  // if(res){
  //   return res;
  // }
  return await loadModelJson();
}

export const loadModelJson = async () => {
  const prefix = publicPath + '/modules/'
  const p = prefix + 'index.json';
  const t = await loadJson(p);
  if(!t) return ;
  const ds = await Promise.all(t.map(n => loadJson(prefix + n + '.json')));
  const data = Object.fromEntries(ds.map(d => [d.key,d]))
  saveModelData(data)
  //
  return data;
}

//
import axios from "axios";
export const loadJson = async (path) => {
  const url = '/' + path;
  try {
    const res = await axios({url,method:'get'})
    return res.data;
  } catch (error) {
    console.error(' === json load error === ',error)
  }
  return undefined
}

// 
const pageLocalKeyPrefix = 'PAGES_DATA_KEY_'
export const loadPageJson = async (name) => {
  const path = publicPath + '/pages/' + name + '.json';
  const d = await loadJson(path);
  savePageJson(name,d)
  return d;
}


export const getPageData = async (name) => {
  const k = pageLocalKeyPrefix + name;
  const t = getLocal(k)
  if(t){
    return t;
  }
  return await loadPageJson(name);
}

export const savePageJson = async(name,data) => {
  const k = pageLocalKeyPrefix + name;
  saveLocal(k,data);
}
const configFormPrefix = 'formconfig'
export const loadConfigJson = async () => {
  const u = publicPath + '/' + configFormPrefix + '/';
  const ns = ['model','page','setting'];
  //
  const [m,p,s] = await Promise.all(ns.map(n => loadJson(u + n + '.json')));
  //
  return {model:m,page:p,setting:s};
}

const pageLocalKey = 'LOCALE_PAGE_LIST_KEY'
export const savePageList = (data) => {
  saveLocal(pageLocalKey,data)
  data.forEach(d => {
    savePageJson(d.name,d)
  })
}

export const loadPageList = async () => {
  const ip = publicPath + '/pages/index.json';
  const ns = await loadJson(ip) || [];
  const list = await Promise.all(ns.map(n => loadJson(`${publicPath}/pages/${n}.json`)))
  //
  if(list.length > 0){
    return list;
  }
  return []
}

export const getPageList = async () => {
  const t = getLocal(pageLocalKey);
  if(t){
    return t;
  }

  return await loadPageList();
}


export const downloadBlob = (blob,name) => {
  const url = URL.createObjectURL(blob);
  downloadFromUrl(url,name)
}

export const downloadFromUrl = (url,name) => {
  const ea = document.createElement('a')
  ea.href=url;
  ea.download = name //file.name
  ea.style.display = 'none'
  ea.click();
    //
  console.log(url,name)
}

// base64 转码
export const img2base64 = (img) => {
  return new Promise((resolve,reject) => {
    resolve(true)
  })
}